package com.dwy2002.product.impl;

import cn.hutool.core.bean.BeanUtil;
import com.aliyun.oss.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dwy2002.common.exception.EmptyIdException;
import com.dwy2002.pojo.po.product.ProductReviews;
import com.dwy2002.pojo.po.users.Users;
import com.dwy2002.pojo.vo.product.ProductReviewsVO;
import com.dwy2002.pojo.vo.product.UserReviewsVO;
import com.dwy2002.product.mapper.ProductReviewsMapper;
import com.dwy2002.product.service.IProductReviewsService;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.dwy2002.common.utils.JsonConversionUtils.convertToType;
import static com.dwy2002.common.utils.Utils.isEmptyOrNull;
import static com.dwy2002.common.utils.Utils.isListEmpty;
import static com.dwy2002.enums.rabbit.ReviewsRabbitConstants.*;

/**
 * @author 杜伟毅
 * @version 1.0
 * @since 2025/02/17
 */
@Service
@RequiredArgsConstructor
public class ProductReviewsServiceImpl extends ServiceImpl<ProductReviewsMapper, ProductReviews> implements IProductReviewsService {
    private final RabbitTemplate rabbitTemplate;

    /**
     * 根据商品id获取评论
     *
     * @param id 商品id
     * @return 商品评论返回类
     * @author 杜伟毅
     * @since 2025/2/27 0027 22:18
     */
    @Override
    public List<ProductReviewsVO> getProductReviews(String id) {
        //id为空则报错
        if (isEmptyOrNull(id)) throw new EmptyIdException("getProductReviews");

        // 1. 查询商品评论
        LambdaQueryWrapper<ProductReviews> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ProductReviews::getProductId, id);
        List<ProductReviews> reviews = list(lqw);
        if (isListEmpty(reviews)) {
            return Collections.emptyList();
        }

        // 2. 批量查询关联用户
        Set<String> userIds = reviews.stream()
                .map(ProductReviews::getUserId)
                .collect(Collectors.toSet());

        //发送RabbitMQ请求
        sendUserIdsToRabbitMQ(userIds, id);

        //接收用户数据（含超时）
        List<Users> usersList = receiveUserDataWithTimeout();

        Map<String, Users> userMap =
                usersList.stream()
                        .collect(Collectors.toMap(Users::getId, u -> u));

        // 3. 数据转换与关联
        return reviews.stream()
                .map(review -> {
                    ProductReviewsVO vo = BeanUtil.copyProperties(review, ProductReviewsVO.class);
                    Users user = userMap.get(review.getUserId());
                    if (user != null) {
                        vo.setUser(BeanUtil.copyProperties(user, UserReviewsVO.class));
                    }
                    return vo;
                }).collect(Collectors.toList());
    }

    /**
     * 根据商品id删除评论
     *
     * @param productIds 商品id集合
     * @author 杜伟毅
     * @since 2025/3/2 0002 17:04
     */
    @Override
    public void deleteReviews(List<String> productIds) {
        if (isListEmpty(productIds)) throw new EmptyIdException("deleteImage");
        LambdaQueryWrapper<ProductReviews> lqw = new LambdaQueryWrapper<>();
        lqw.in(ProductReviews::getProductId, productIds);
        remove(lqw);
    }

    // 子方法：-----------------------------------------------------------------

    /**
     * 发送RabbitMQ请求
     *
     * @author 杜伟毅
     * @since 2025/3/24 0024 22:44
     */
    private void sendUserIdsToRabbitMQ(Set<String> userIds, String correlationId) {
        rabbitTemplate.convertAndSend(
                REVIEWS_REQUEST_EXCHANGE,
                REVIEWS_REQUEST_ROUTING_KEY,
                userIds,
                message -> {
                    message.getMessageProperties().setReplyTo(REVIEWS_RESPONSE_QUEUE);
                    message.getMessageProperties().setCorrelationId(correlationId);
                    return message;
                });
    }

    /**
     * 子方法：接收用户数据（含超时）
     *
     * @author 杜伟毅
     * @since 2025/3/24 0024 22:49
     */
    private List<Users> receiveUserDataWithTimeout() {
        // 注册回调监听器
        rabbitTemplate.setReplyTimeout(30000); // 30秒超时
        try {
            Object received = rabbitTemplate.receiveAndConvert(REVIEWS_RESPONSE_QUEUE);
            return convertToType(received, new TypeReference<>() {
            });
        } catch (AmqpException e) {
            throw new ServiceException("数据响应超时");
        }
    }

}
